package com.binarycat.dynamiclimit.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.binarycat.dynamiclimit.DynamicLimiterManager;
import com.binarycat.dynamiclimit.bean.DynamicLimitData;
import com.binarycat.dynamiclimit.bean.DynamicLimiterConfig;
import com.binarycat.dynamiclimit.collector.AbstractLimitDataCollector;
import com.binarycat.dynamiclimit.limiter.DynamicLimiter;

/**
 * 动态限流拦截器
 * 
 * @author jjb
 * @date 2018/08/06
 */
public class DynamicLimitInterceptor implements HandlerInterceptor, ApplicationContextAware {
    private DynamicLimiterManager dynamicLimiterManager;
    
    private HandlerAfterLimit handlerAfterLimit;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        DynamicLimiter limiter = dynamicLimiterManager.getDynamicLimiter();
        DynamicLimitData limitData = dynamicLimiterManager.getLimitData();
        DynamicLimiterConfig limiterConfig = dynamicLimiterManager.getDynamicLimiterConfig();
        if (limiter.acquireLimitStatus(request, handler, limitData, limiterConfig)) {
            if(handlerAfterLimit!=null) {
                handlerAfterLimit.handle(request,response);
            }
            return false;
        }

        // 收集方法执行信息
        AbstractLimitDataCollector limitDataCollector = dynamicLimiterManager.getLimitDataCollector();
        limitDataCollector.preCollectMethodExecutionInformation(request, handler, dynamicLimiterManager);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {

        AbstractLimitDataCollector limitDataCollector = dynamicLimiterManager.getLimitDataCollector();
        limitDataCollector.postCollectMethodExecutionInformation(request, handler, ex, dynamicLimiterManager);

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        try {
            this.handlerAfterLimit=applicationContext.getBean(HandlerAfterLimit.class);
        } catch (Exception e) {
        }
        this.dynamicLimiterManager = applicationContext.getBean(DynamicLimiterManager.class);
    }
}
